package com.cch.demo.sys.realm;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cch.demo.sys.domain.Permission;
import com.cch.demo.sys.domain.User;
import com.cch.demo.sys.service.PermissionService;
import com.cch.demo.sys.service.RoleService;
import com.cch.demo.sys.service.UserService;
import com.cch.demo.sys.util.ActiverUser;
import com.cch.demo.sys.util.Constast;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.context.annotation.Lazy;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class UserRealm extends AuthorizingRealm {

    @Resource
    @Lazy //只有使用的时候再加载
    private UserService userServiceImpl;

    @Resource
    @Lazy
    private PermissionService permissionServiceImpl;

    @Resource
    @Lazy
    private RoleService roleServiceImpl;

    @Override
    public String getName() {
        return this.getClass().getSimpleName();
    }
    /**
     * 做认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String loginname = authenticationToken.getPrincipal().toString();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("loginname",loginname);
        User user =  userServiceImpl.getOne(queryWrapper);
        if (user!=null){
            ActiverUser activerUser = new ActiverUser();
            activerUser.setUser(user);

            //根据用户ID查询拥有的rid
            List<Integer> rids = roleServiceImpl.queryUserRoleIdsByUid(user.getId());
            //根据rid查询菜单权限ID 过程中可能会有重复

            //set用来过滤重复的 set中为菜单权限ID
            Set<Integer> set = new HashSet<>();
            for(Integer rid:rids){
                List<Integer> pids =  roleServiceImpl.queryRolePermissionByRid(rid);
                set.addAll(pids);
            }

            List<String> percode = new ArrayList<>();
            if(set!=null&&set.size()>0){
                QueryWrapper<Permission> qw = new QueryWrapper<>();
                //设置只能查询权限
                qw.eq("type", "permission");
                qw.eq("available", Constast.AVAILABLE_TRUE);
                qw.in("id",set);
                List<Permission> pers = permissionServiceImpl.list(qw);

                for(Permission p:pers){
                    percode.add(p.getPercode());
                }
            }
            activerUser.setPermissions(percode);

            ByteSource source = ByteSource.Util.bytes(user.getSalt());
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(activerUser,user.getPwd(),source,this.getName());

            return  simpleAuthenticationInfo;
        }
        return null;
    }


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo simple=new SimpleAuthorizationInfo();
        ActiverUser activerUser=(ActiverUser) principalCollection.getPrimaryPrincipal();
        User user=activerUser.getUser();
        List<String> permissions = activerUser.getPermissions();
        if(user.getType()==Constast.USER_TYPE_SUPER) {
            //超级管理员
            simple.addStringPermission("*:*");
        }else {
            if(null!=permissions&&permissions.size()>0) {
                simple.addStringPermissions(permissions);
            }
        }

        return simple;
    }


}
